package com.sfac.day03.modules.common.controller;

import com.sfac.day03.modules.common.entity.ExceptionLog;
import com.sfac.day03.modules.common.entity.ResultEntity;
import com.sfac.day03.modules.common.service.ExceptionLogService;
import com.sfac.day03.util.IPUtil;
import com.sfac.day03.util.StringUtil;
import io.micrometer.core.instrument.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;


@ControllerAdvice
public class ExceptionHandlerController {

    private final static Logger LOGGER =
            LoggerFactory.getLogger(ExceptionHandlerController.class);
    @Autowired
    private ExceptionLogService exceptionLogService;

    @ExceptionHandler(value = ArithmeticException.class)
    @ResponseBody
    public ResultEntity<String> exceptionHandlerFor403(HttpServletRequest request,
                                                       Exception ex) {
        insertExceptionLog(request, ex);
        return new ResultEntity<>(ResultEntity.ResultStatus.FAILED.code,
                "Internal error", "/common/403");
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResultEntity<String> exceptionHandler(HttpServletRequest request,
                                                 Exception ex) {
        insertExceptionLog(request, ex);
        return new ResultEntity<>(ResultEntity.ResultStatus.FAILED.code,
                "Internal error", "/common/500");
    }

    public void insertExceptionLog(HttpServletRequest request, Exception ex) {
        ex.printStackTrace();
        LOGGER.debug("======== Log exception into db ========");

        ExceptionLog exceptionLog = new ExceptionLog();
        exceptionLog.setIp(IPUtil.getIpAddr(request));
        exceptionLog.setPath(request.getServletPath());
        HandlerMethod handlerMethod = (HandlerMethod) request.getAttribute(
                "org.springframework.web.servlet.HandlerMapping.bestMatchingHandler");
        if (handlerMethod != null) {
            exceptionLog.setClassName(handlerMethod.getBeanType().getName());
            exceptionLog.setMethodName(handlerMethod.getMethod().getName());
        }
        exceptionLog.setExceptionType(ex.getClass().getSimpleName());
        exceptionLog.setExceptionMessage(StringUtils.isBlank(ex.getMessage()) ? "" :
                StringUtil.splitString(ex.getMessage().trim(), 200));
        exceptionLog.setCreateDate(LocalDateTime.now());

        exceptionLogService.insertExceptionLog(exceptionLog);
    }

}

